package com.demo.webapp.jcaptcha.security.authentication;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.util.Assert;

import com.demo.security.core.SecurityMessageSource;
import com.demo.webapp.jcaptcha.core.validation.JCaptchaValidator;

public class CaptchaAuthenticationProvider implements AuthenticationProvider, InitializingBean, MessageSourceAware { 

    protected MessageSourceAccessor messages = SecurityMessageSource.getAccessor();
    
    /**
     * 验证码验证类
     */
    private JCaptchaValidator captchaValidator;
    
	@Override
	public void setMessageSource(MessageSource messageSource) {
		this.messages = new MessageSourceAccessor(messageSource);
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(this.captchaValidator, "未找到JCaptchaValidator验证器.");
	}
	
	@Override
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		if (!supports(authentication.getClass())) {
			return null;
		}
		String captchaId;
		CaptchaAndUsernamePasswordAuthenticationToken token = (CaptchaAndUsernamePasswordAuthenticationToken) authentication;
		if (token.getCaptcha() != null) {
			if (token.getCaptcha() instanceof String) {
				captchaId = token.getSessionId();
				if (!captchaValidator.validate(captchaId, token.getCaptcha().toString())) {
					throw new CaptchaException(messages.getMessage("RememberMeAuthenticationProvider.incorrectKeysss", "验证码不正确."));
				};
			}
		}
		return null;
	}
	
	@Override
	public boolean supports(Class<?> authentication) {
		 return (CaptchaAndUsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
	}

	public void setCaptchaValidator(JCaptchaValidator captchaValidator) {
		this.captchaValidator = captchaValidator;
	}
}
